# sweep_v_fixed.py
# 用法：把 file_path 换成你的程序路径（同目录且名为 problem3_sequential.py 则可不改）
import importlib.util
import sys, io, contextlib, random
import numpy as np
import pandas as pd

def load_module(file_path: str, name: str = "target_mod"):
    spec = importlib.util.spec_from_file_location(name, file_path)
    mod = importlib.util.module_from_spec(spec)
    sys.modules[name] = mod
    assert spec.loader is not None
    spec.loader.exec_module(mod)
    return mod

class SuppressToExcel:
    """临时禁用 pandas.DataFrame.to_excel，避免被被调用程序每次写盘"""
    def __enter__(self):
        self._orig = pd.DataFrame.to_excel
        pd.DataFrame.to_excel = lambda *args, **kwargs: None
        return self
    def __exit__(self, exc_type, exc, tb):
        pd.DataFrame.to_excel = self._orig

def sweep(file_path: str, v_start=121.00, v_end=121.14, step=0.02, seed=42):
    mod = load_module(file_path)
    results = []
    # v_vals = np.round(np.arange(v_start, v_end + 1e-9, step), 1)
    v_vals = np.round(np.arange(v_start, v_end + 1e-9, step), 2)

    for v in v_vals:
        # 固定随机种子，保证不同 v 的可重复性（同一条随机序列）
        random.seed(seed)
        np.random.seed(seed)

        # 设置被调用模块的全局速度
        mod.v_fixed = float(v)

        # 调用优化：静默 stdout + 禁写 Excel
        with SuppressToExcel(), contextlib.redirect_stdout(io.StringIO()):
            drops, bursts, total, indiv_times, _ = mod.sequential_optimize()

        results.append({
            "v_fixed": v,
            "total": float(total),
            "indiv_time_1": float(indiv_times[0]),
            "indiv_time_2": float(indiv_times[1]),
            "indiv_time_3": float(indiv_times[2]),
        })
        print(f"v_fixed={v:.2f} 完成，total={total:.3f}, indiv_times={[f'{t:.3f}' for t in indiv_times]}")

    df = pd.DataFrame(results)
    df.to_csv("sweep_v_fixed_results.csv", index=False, encoding="utf-8-sig")
    return df

if __name__ == "__main__":
    df = sweep("problem3.py")
    print(df.to_string(index=False))
    print("\n已保存：sweep_v_fixed_results.csv")
